Механизм обработки событий в Java весьма прост, достаточно мощный и очень гибкий. Не верите? Судите сами:
AnyComponent.addActionListener(ObWhoMustHandleEvents);Одному компоненту можно назначить, таким образом, несколько обработчиков событий. Каким же свойством должен объект, который сможет обработать событие (в нашем примере ObWhoMustHandleEvent)? Все очень просто - он должен имплементировать интерфейс ActionListener. В интерфейсе всего один метод: actionPerformed(ActionEvent e), который и нужно реализовать вашему объекту - обработчику события. Этот метод выполнится при возникновении события.
По аналогичной схеме обрабатываются и другие события. Например, чтоб обработать события от мыши, указываем функцией addMouseListener(ObWhoMustHandleEvents) объект, который будет их обрабатывать, этот объект должен имплементировать интерфейс MouseListener. Здесь нужно реализировать уже 5 функций mousePressed(MouseEvent e), mouseReleased(MouseEvent e), mouseEntered(MouseEvent e), mouseExited(MouseEvent e) и mouseClicked(MouseEvent e). И так далее. Вот функции которыми обладают все компоненты для регистрации обработчиков событий:
public class MainWindow extends JFrame implements WindowListener { //........... //скажем объекту окна пусть сам свои событыя и обрабатывает addWindowListener(this); //реализируем методы интерфейса WindowListener public void windowActivated(WindowEvent e) { doSomething(); } public void windowClosing(WindowEvent e) {} public void windowClosed(WindowEvent e) {} public void windowOpened(WindowEvent e) {} public void windowIconified(WindowEvent e) {} public void windowDeiconified(WindowEvent e) {} public void windowDeactivated(WindowEvent e) {} //........... }Чтоб обработать событие активации в функции windowActivated(WindowEvent e) нам пришлось еще 6 пустых функций вписать ибо раз взялись имплементировать интерфейс то надо сделать это полностью, иначе класс свой абстрактным сделаем. Чтоб не вписывать пустые функции придуманы классы-адаптеры которые имплементируют соответствующие интерфейсы и содержат реализацию их методов по умолчанию. Например, для событий окна существует WindowAdapter, для событий мыши - MouseAdapter. Ваш класс обрабатывающий событие может унаследовать такой класс-адаптер и перегрузить нужный Вам метод для обработки конкретного события. Но как это использовать в примере выше? Ведь наш класс уже наследуется от JFrame а многократного наследования в Java нету! Выход простой - создадим специальный внутренний класс - обработчик событий окна (внутренний лучше потому что он будет иметь доступ к всем полям содержащего его класса). Пример:
public class MainWindow extends JFrame { //........... //Действие 1 //скажем объекту окна что обрабатывать //его события будет класс OurListener //создавая его сходу addWindowListener(new OurListener()); //Действие 2 //реализируем внутренний класс OurListener class OurListener extends WindowAdapter { //перегружаем нужный нам метод public void windowActivated(WindowEvent e) { doSomething(); } } //........... }А теперь оба окурка давим одновременно:) - перепишем этот код объединив действия 1 и 2 в одно:
public class MainWindow extends JFrame { //........... //скажем объекту окна что обрабатывать //его события будет класс Х! //создадим его сходу с помощью //конструктора родительского класса //и тут же перегрузим нужный нам метод! addWindowListener(new WindowAdapter() { public void windowActivated(WindowEvent e) { doSomething(); } }); //........... }Ну как вам аргументец функции addWindowListener? Какое у этого класса название? Нету у него имени (да и незачем в принципе оно ему), он является потомком класса WindowAdapter один из методов которого мы перегрузили, большего нам от него и не надобно.
Осталось нам разобраться что за аргументы передаются в функции-обработчики событий. Как видим, они разные: в случае с событием типа action в функции actionPerformed аргументом есть объект типа ActionEvent, в функциях событий окна - аргументом есть WindowEvent, для обработчиков событий мыши аргументом будет MouseEvent. Как Вы уже догадались это все одного поля ягоды. Они все содержат информацию о соответствующем событии. Их предком является класс EventObject. С помощью метода getSource, которым обеспечивает данный класс своих потомков, Вы можете получить объект создавший событие. Кроме того у каждого из вышеперечисленных классов можно узнать специфические детали для каждого события, например у объекта MouseEvent можно узнать координаты мыши во время возникновения события, количество кликов, какой кнопкой кликали и т.д.
import java.awt.*; import javax.swing.*; //нижеследующее импортируем для работы с событиями import java.awt.event.*; public class EventApplet extends JApplet implements ActionListener { JButton button; JTextArea ButtArea, MouseArea; public void init() { Container contPane = getContentPane(); contPane.setLayout(new BoxLayout(contPane, BoxLayout.Y_AXIS)); button=new JButton("Our Button"); button.addActionListener(this); ButtArea=new JTextArea(10,10); //поместим наши JTextArea на панель которая //может создать скроллинг JScrollPane ScrollPane_butt = new JScrollPane(ButtArea); //окружим эту панель рамкой с заголовком ScrollPane_butt.setBorder(BorderFactory.createTitledBorder("Button actions:")); //тут аналогично... MouseArea=new JTextArea(10,10); JScrollPane ScrollPane_mouse = new JScrollPane(MouseArea); ScrollPane_mouse.setBorder(BorderFactory.createTitledBorder("Mouse actions:")); //поместим нашу кнопку и JScrollPane панели //которые содержат в себе наши JTextArea //на главную панель апплета contPane.add(button); contPane.add(ScrollPane_butt); contPane.add(ScrollPane_mouse); //назначим територии апплета обработчик событий //мыши создав его на ходу addMouseListener(new MouseAdapter(){ public void mouseClicked(MouseEvent e) { MouseArea.append("Mouse clicked"+e.getClickCount()+"times"+"\n"); } public void mouseEntered(MouseEvent e) { MouseArea.append("Mouse entered"+"\n"); } public void mouseExited(MouseEvent e) { MouseArea.append("Mouse exited"+"\n"); } }); } //обработаем нажатие кнопки public void actionPerformed(ActionEvent e) { ButtArea.append("Button Clicked" + "\n"); } }Компилируем, смотрим. У кого не получилось - грузите проект, там кроме апплета есть еще аналогичное приложение (EventApp). Кстати, Вы заметили что при компиляции кроме файла главного класса еще какой-то файл EventApplet$1.class получается? Это не спам! Это наш анонимный внутренний класс-обработчик событий мыши. Ну теперь можно покликать по кнопке, повходить-выходить на территорию панели апплета не занятую нашими компонентами (возле кнопки ее больше всего должно быть) и покликать по этой территории. Попробуйте сделать многократный клик и посмотрите на запись событий в нижней текстовой области. При переполнении текстовых областей должна прокрутка появляться - не даром же мы их на специальные панели ставили!